/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 pjoc.pub, blademainer.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package pub.pjoc.pay.order.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pub.pjoc.pay.order.OrderGenerator;
import pub.pjoc.pay.order.pattern.*;

/**
 * Default implements of OrderGenerator.
 *
 * @author blademainer
 * @version 2016-09-17 01:03
 */
@Service
public class OrderGeneratorImpl implements OrderGenerator {
  @Autowired
  private PatternWordGeneratorManager patternWordGeneratorManager;

  private static final Logger logger = LoggerFactory.getLogger(OrderGeneratorImpl.class);
  // datemachineIIIIII
  public static final PatternWord[] DEFAULT_PATTERN_WORDS = {PatternWord.PATTERN_DATE,
      PatternWord.PATTERN_MACHINE, PatternWord.PATTERN_INDEX, PatternWord.PATTERN_INDEX,
      PatternWord.PATTERN_INDEX, PatternWord.PATTERN_INDEX, PatternWord.PATTERN_INDEX,
      PatternWord.PATTERN_INDEX};

  private PatternWord[] patternWords = DEFAULT_PATTERN_WORDS;

  @Override
  public String generateOrderNumber() {

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < patternWords.length; i++) {
      PatternWord patternWord = patternWords[i];

      PatternWordGenerator generator = patternWordGeneratorManager.getGenerator(patternWord);
      if (generator == null) {
        logger.error("Pattern word: {} could'nt found generator!", patternWord);
        continue;
      }

      // find together words
      boolean mustTogether = patternWord.isMustTogether();
      if (mustTogether) {
        int size = 0;
        for (; i < patternWords.length; i++) {
          if (!patternWord.equals(patternWords[i])) {
            break;
          }
          size++;
        }
        String word = generator.generate(size);
        if (logger.isDebugEnabled()) {
          logger.debug("Pattern word: {} generate word: {}", patternWord, word);
        }
        builder.append(word);
        continue;
      }

      String word = generator.generate(1);
      builder.append(word);
    }
    return builder.toString();
  }


  @Override
  public void setPattern(String pattern) throws PatternWordNotSupportException {
    boolean match = PatternParser.matches(pattern);
    if (!match) {
      logger.error("Pattern: {} is illegal!");
      throw new PatternWordNotSupportException(pattern);
    }

    PatternWord[] patternWords = PatternParser.parsePatternWords(pattern);
    if (logger.isDebugEnabled()) {
      logger.debug("Parse pattern string: {} to words: {}", pattern, patternWords);
    }
    this.patternWords = patternWords;
  }

  public PatternWordGeneratorManager getPatternWordGeneratorManager() {
    return patternWordGeneratorManager;
  }

  public void setPatternWordGeneratorManager(PatternWordGeneratorManager patternWordGeneratorManager) {
    this.patternWordGeneratorManager = patternWordGeneratorManager;
  }

  public static void main(String[] args) throws PatternWordNotSupportException {
    String pattern = "datemachineIIIIII";
    OrderGeneratorImpl orderGenerator = new OrderGeneratorImpl();
    orderGenerator.setPattern(pattern);
  }

}
